local AddOnName, Env = ...; local ADDON, DEV = Env[1], Env[1].development
-- ~~| Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local DiesalGUI 	= LibStub('DiesalGUI-1.0')
local DiesalStyle = LibStub("DiesalStyle-1.0")
local DiesalTools = LibStub('DiesalTools-1.0')
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local tostring										= tostring
local format 										= string.format
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

-- ~~| ConfigToggle |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type 		= 'ConOption'
local Version 	= 1
-- ~~| ConfigToggle StyleSheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local styleSheet = {
	['frame-white'] = {
		type			= 'outline',
		layer			= 'OVERLAY',
		color			= 'ffffff',
		alpha			= 0,
	},	
	['nameFrame-red'] = {
		type			= 'outline',
		layer			= 'OVERLAY',
		color			= 'ff0000',
		alpha			= 0,
	},		
	['name-color'] = {		
		type			= 'Font',		
		color			= 'bfbfbf',		
	},
	['divider-top'] = {
		type			= 'texture',
		layer			= 'ARTWORK',		
		color			= 'ffffff',
		alpha			= .04,	
		offset		= {-1,-1,-2,nil},	
		height		= 1,
	},
	['divider-black'] = {
		type			= 'texture',
		layer			= 'ARTWORK',		
		color			= '000000',	
		offset		= {0,0,-3,nil},	
		height		= 1,
	},
	['divider-bottom'] = {
		type			= 'texture',
		layer			= 'ARTWORK',		
		color			= 'ffffff',
		alpha			= .04,	
		offset		= {-1,-1,-4,nil},	
		height		= 1,
	},		
	['input-background'] = {	
		type			= 'texture',
		layer			= 'BACKGROUND',
		color			= '000000',
		offset		= 0,		
	},
	['input-gradient'] = {			
		type			= 'texture',
		layer			= 'BORDER',
		gradient		= 'VERTICAL',							
		color			= 'ffffff',	
		alpha 		= 0,
		alphaEnd		= .1,
		offset		= -1,		
	},
	['input-outline'] = {		
		type			= 'outline',
		layer			= 'BORDER',	
		color			= '000000',
		offset		= 0,		
	},	
	['input-inline'] = {		
		type			= 'outline',
		layer			= 'BORDER',
		gradient		= 'VERTICAL',	
		color			= 'ffffff',
		alpha 		= .02,
		alphaEnd		= .05,
		offset		= -1,	
	},	
	['input-hover'] = {		
		type			= 'outline',
		layer			= 'HIGHLIGHT',
		color			= 'ffffff',
		alpha 		= .12,	
		offset		= -1,	
	},		
}
local hotkeyStyleSheet = {
	['frame-arrow'] = {
		type			= 'texture',
		layer			= 'BORDER',
		alpha 		= 0,
	},
}
-- ~~| ConfigToggle Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

-- ~~| ConfigToggle Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local methods = {
	['OnAcquire'] = function(self)		
		self:AddStyleSheet(styleSheet)
		-- self:AddStyleSheet(wireFrameSheet)
		self:Show()
		
		self.divider:Hide()	
		self.checkBox:Hide()	
		self.spinner:Hide()
		self.input:Hide()
		self.selecter:Hide()		
		self.hotkey:Hide()
		self.nameFrame:Hide()
		self.nameFrame:SetPoint("BOTTOMRIGHT",-10,3)
		self:SetHeight(18)	 
	end,
	['OnRelease'] = function(self)

	end,
	['ApplySettings'] = function(self)		
		local optionData 	= self.settings.data		
		local optionType 	= optionData.type:lower()
		local widgetWidth = optionData.width and DiesalTools:Round(optionData.width,2)-1 or 50		
			
		if self.settings.position == 1 then
			self:SetPoint('TOPLEFT',0,-self.settings.padTop) 
			self:SetPoint('RIGHT')			
		else			
			self:SetPoint('TOPLEFT',self.settings.parentObject.children[self.settings.position-1].frame,'BOTTOMLEFT',0,0)
			self:SetPoint('RIGHT')		
		end		
		
		if optionData.name then 
			self.nameFrame:Show()
			self.name:SetText(optionData.name)			
		end
		
		if optionData.toggle ~= false then  
			self.checkBox:Show()					
		end			
		
		if optionType == 'spinner' then			
			self.spinner:Show() 
			self.spinner:SetSettings({
				min		= optionData.min 		or 0,
				max		= optionData.max 		or 100,
				step		= optionData.step 	or 5,
				width		= widgetWidth,			
			},true)			
			self.nameFrame:SetPoint("BOTTOMRIGHT",-( 10 + widgetWidth),3)
		elseif optionType == 'input' then
			self.input:Show()	
			self.input:SetWidth(widgetWidth)				
			self.nameFrame:SetPoint("BOTTOMRIGHT",-( 10 + widgetWidth),3)
		elseif optionType == 'select' then
			self.selecter:Show()			
			self.selecter:SetSettings({ width = widgetWidth},true)	
			self.selecter:SetList(optionData.values)			
			self.nameFrame:SetPoint("BOTTOMRIGHT",-( 10 + widgetWidth),3)
		elseif optionType == 'hotkey' then
			self.hotkey:SetSettings({width = 50},true)	
			self.hotkey:Show()
			self.nameFrame:SetPoint("BOTTOMRIGHT",-( 10 + widgetWidth),3)				
		elseif optionType == 'divider' then
			self.checkBox:Hide()
			self.divider:Show()					
			self:SetHeight(7)	
		end		
	end,	
	['Update'] = function(self,db)
		local optionData 	= self.settings.data		
		local optionType 	= optionData.type:lower()
		if optionType == 'divider' then return end
		
		self.settings.db = db
		
		if optionData.toggle ~= false then 
			self.checkBox:SetChecked(db.enable)
			_G[db.id..'_Enable'] = db.enable			
			ADDON:Debug("scriptVars",db.id..'_Enable',db.enable)						
		end	
		-- ~~  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		if optionType == 'toggle' then			
			-- --
		elseif optionType == 'spinner' then			
			_G[db.id..'_Value'] = db.value
			ADDON:Debug("scriptVars",db.id..'_Value',db.value)			
			self.spinner:SetNumber(db.value)
		elseif optionType == 'input' then			
			_G[db.id..'_Value'] = db.value
			ADDON:Debug("scriptVars",db.id..'_Value',db.value)				
			self.input:SetText(db.value)
			self.input:SetCursorPosition(0)
		elseif optionType == 'select' then
			_G[db.id..'_Value'] = db.value
			ADDON:Debug("scriptVars",db.id..'_Value',db.value)			
			self.selecter:SetValue(db.value)			
		elseif optionType == 'hotkey' then
			_G[db.id..'_Value'] = db.value
			ADDON:Debug("scriptVars",db.id..'_Value',db.value)						
			self.hotkey:SetValueTable(db.value)
		end		
	end,
	['Lock'] = function(self,lock)		
		self.checkBox:Disable()		
		self.spinner:EnableMouse(false)
		self.input:EnableMouse(false)
		self.selecter:EnableMouse(false)
		self.hotkey:EnableMouse(false)
	end,
	['Unlock'] = function(self,lock)		
		self.checkBox:Enable()		
		self.spinner:EnableMouse(true)
		self.input:EnableMouse(true)
		self.selecter:EnableMouse(true)
		self.hotkey:EnableMouse(true)
	end,		
}
-- ~~| ConfigToggle Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
	local self 		= DiesalGUI:CreateObjectBase(Type)
	local frame		= CreateFrame('Frame',nil,UIParent)		
	self.frame		= frame	
	-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	self.defaults = {
		
	}
	-- ~~ Registered Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	local checkBox = DiesalGUI:Create('CheckBox')
	checkBox:SetParent(frame)	
	checkBox:SetPoint("TOPLEFT",2,-3)	
	checkBox:SetEventListener('OnValueChanged', function(this,event,value)
		self.settings.db.enable = value		
		_G[self.settings.db.id..'_Enable'] = value
		ADDON:Debug("scriptVars",self.settings.db.id..'_Enable',value)			
	end)			
	checkBox:SetEventListener('OnEnter', function(this)
		if not ADDON.RotationConfig.db.tooltips then return end
		GameTooltip:SetOwner(checkBox.frame, "ANCHOR_TOPLEFT",0,2) 		
		GameTooltip:AddLine('enable option')
		GameTooltip:Show()
	end)
	checkBox:SetEventListener('OnLeave', function(this)
		GameTooltip:Hide()
	end)
	
	local nameFrame = self:CreateRegion("Frame", 'nameFrame', frame)
	nameFrame:SetPoint("TOPLEFT",16,-3)		
	nameFrame:SetScript('OnEnter', function(this)		
		if not ADDON.RotationConfig.db.configTooltips then return end
		if not self.settings.data.tooltip then return end
		GameTooltip:SetOwner(nameFrame, "ANCHOR_TOPLEFT",0,2) 		
		GameTooltip:AddLine('|cffff7f00'..self.settings.data.tooltip,nil,nil,nil,1)
		GameTooltip:Show()
	end)
	nameFrame:SetScript('OnLeave', function(this)		
		GameTooltip:Hide()
	end)
	
	local name = self:CreateRegion("FontString", 'name', nameFrame)
	name:SetPoint("TOPLEFT",0,-1)
	name:SetPoint("BOTTOMRIGHT",4,-2)
	name:SetJustifyV("TOP")		
	name:SetJustifyH("LEFT")
	name:SetWordWrap(false)
	
	local spinner = DiesalGUI:Create('Spinner')	
	spinner:SetParent(frame)
	spinner:SetPoint('TOPRIGHT',-4,-1)	
	spinner:SetEventListener('OnValueChanged', function(this,event,userInput,number)			
		if not userInput then return end	
		self.settings.db.value = number
				
		_G[self.settings.db.id..'_Value'] = number
		ADDON:Debug("scriptVars",self.settings.db.id..'_Value',number)		
		
	end)
	spinner:SetEventListener('OnEnter', function(this)			
		if not ADDON.RotationConfig.db.configTooltips and not ADDON.RotationConfig.db.tooltips then return end
		GameTooltip:SetOwner(spinner.frame, "ANCHOR_TOPRIGHT",0,2) 		
		if ADDON.RotationConfig.db.configTooltips and self.settings.data.widgetTooltip then
			GameTooltip:AddLine('|cffff7f00'..self.settings.data.widgetTooltip,nil,nil,nil,1)
		end
		if ADDON.RotationConfig.db.tooltips then
			GameTooltip:AddLine('|cff00aaffMouse Wheel:|r Adjust value by '..this.settings.step)
		end
		
		GameTooltip:Show()
	end)
	spinner:SetEventListener('OnLeave', function(this)			
		GameTooltip:Hide()
	end)
	
	local input = self:CreateRegion("EditBox", 'input', frame)	
	input:SetHeight(16)	
	input:SetPoint('TOPRIGHT',-4,-1)	
	input:SetAutoFocus(false)			
	input:SetJustifyH("CENTER")
	input:SetJustifyV("CENTER")	
	input:SetTextInsets(1,0,2,0)
	input:SetTextColor(.8,.8,.8,1)		
	input:SetScript('OnEnterPressed',  function(this,...)				
		if this:GetText() ~= self.settings.oldInput then
			self.settings.oldInput = this:GetText()	
			self.settings.db.value = this:GetText()
			
			_G[self.settings.db.id..'_Value'] = this:GetText()
			ADDON:Debug("scriptVars",self.settings.db.id..'_Value',this:GetText())			
		end
		DiesalGUI:ClearFocus()		
	end)				
	input:HookScript('OnEscapePressed', function(this,...)				
		this:SetText(self.settings.oldInput)		
	end)
	input:HookScript('OnEditFocusLost', function(this,...)				
		this:SetText(self.settings.oldInput)		
	end)	
	input:HookScript('OnEditFocusGained', function(this)				
		self.settings.oldInput = this:GetText()			
	end)	
	input:SetScript("OnEnter",function(this,...)		
		if not ADDON.RotationConfig.db.configTooltips then return end
		if not self.settings.data.widgetTooltip then return end
		
		GameTooltip:SetOwner(editBox, "ANCHOR_TOPRIGHT",0,2) 	
		GameTooltip:AddLine('|cffff7f00'..self.settings.data.widgetTooltip,nil,nil,nil,1)		
		GameTooltip:Show()		
	end)
	input:SetScript("OnLeave", function(this,...)		
		GameTooltip:Hide()				
	end)		
	
	local selecter = DiesalGUI:Create('Dropdown')
	selecter:AddStyleSheet(hotkeyStyleSheet) 
	selecter:SetParent(frame)
	selecter:SetPoint('TOPRIGHT',-4,-1)	
	selecter.text:SetPoint("BOTTOMRIGHT", -4, -1)
	selecter.text:SetJustifyH("CENTER")			
	selecter:SetEventListener('OnValueSelected', function(this,event,key)			
		self.settings.db.value = key
		_G[self.settings.db.id..'_Value'] = key
		ADDON:Debug("scriptVars",self.settings.db.id..'_Value',key)			
	end)
	selecter:SetEventListener('OnEnter', function(this)			
		if not ADDON.RotationConfig.db.configTooltips then return end
		if not self.settings.data.widgetTooltip then return end
		GameTooltip:SetOwner(selecter.frame, "ANCHOR_TOPRIGHT",0,2) 		
		GameTooltip:AddLine('|cffff7f00'..self.settings.data.widgetTooltip,nil,nil,nil,1)		
		GameTooltip:Show()
	end)
	selecter:SetEventListener('OnLeave', function(this)			
		GameTooltip:Hide()
	end)
	
	local hotkey = DiesalGUI:Create('Dropdown') 
	hotkey:AddStyleSheet(hotkeyStyleSheet)
	hotkey:SetParent(frame)
	hotkey:SetPoint('TOPRIGHT',-4,-1)
	hotkey.text:SetPoint("BOTTOMRIGHT", -4, -1)
	hotkey.text:SetJustifyH("CENTER")
	hotkey:SetSettings({	multiSelect = true},true)		
	hotkey:SetList({ la="LA", ra="RA", ls="LS", rs="RS", lc="LC", rc="RC" },{ "la","ra","ls","rs","lc","rc" })	
	hotkey:SetEventListener('OnValueSelected', function(this,event,key,valuue,selectionTable)			
		self.settings.db.value = selectionTable
		
		_G[self.settings.db.id..'_Value'] = selectionTable
		ADDON:Debug("scriptVars",self.settings.db.id..'_Value',selectionTable)			
	end)
	hotkey:SetEventListener('OnEnter', function(this)			
		if not ADDON.RotationConfig.db.configTooltips and not ADDON.RotationConfig.db.tooltips then return end
		GameTooltip:SetOwner(hotkey.frame, "ANCHOR_TOPRIGHT",0,2) 		
		if ADDON.RotationConfig.db.configTooltips and self.settings.data.widgetTooltip then
			GameTooltip:AddLine('|cffff7f00'..self.settings.data.widgetTooltip)
		end
		if ADDON.RotationConfig.db.tooltips then
			GameTooltip:AddLine('|cff00aaffls: |rLeft Shift |cff00aaffra: |rRight Alt')
			GameTooltip:AddLine('|cff00aaffno selection: |rautomatic use')
		end
		
		GameTooltip:Show()
	end)
	hotkey:SetEventListener('OnLeave', function(this)			
		GameTooltip:Hide()
	end)		
	
	local divider = self:CreateRegion("Frame", 'divider', frame)
	divider:SetAllPoints()
	-- ~~ Frames ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~	
	self.checkBox 	= checkBox
	self.spinner	= spinner
	self.input		= input
	self.selecter	= selecter
	self.hotkey		= hotkey
	-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	for method, func in pairs(methods) do
		self[method] = func
	end	
	-- ~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	DiesalGUI:RegisterObject(self)
	return self
end
DiesalGUI:RegisterObjectConstructor(Type,Constructor,Version)
